Day 8 - HTML Canvas


Posted by hoyi-23 on 2021-07-26

這次的練習會運用到 HTML Canvas Graphics

今天我想自己練習來作一個超級簡易版小畫家,效果包含:

  1. 顏色
  2. 筆刷粗細
  3. 橡皮擦
  4. 放上貼圖(構想)

HTML Canvas

HTML Canvas 會提供一個畫布空間,需要使用到JavaScript來作畫。

如何使用?

Canvas為一個正方形的區塊,預設就是空白的、沒有border。
HTML:

<canvas id="myCanvas" width="200" height="100"></canvas>

JavaScript:
取得 Canvas 的渲染環境及其繪圖函數

const canvas = document.querySelector('#myCanvas');
const ctx = canvas.getContext('2d');

設定 Canvas滿版

但放上去後發現就算更改的寬度和長度,還是無法讓畫布滿版、自適應整個螢幕。

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

基本content樣式設定

前面提到 canvas 就是一個空白的畫布,填上東西靠的是content。
通常會宣告為ctx
我們可以先對ctx最一些基礎的設定(例如: 筆刷大小/ 顏色等)

ctx.strokeStyle = '#bada55';  // 筆觸顏色
ctx.lineJoin = 'round';  // 兩條線交匯處產生 "圓形" 邊角
ctx.lineCap = 'round';  // 筆觸預設為 "圓形"
ctx.lineWidth = 1;  // 筆頭寬度

let isDrawing = false;  // 是否 mousedown下筆狀態

/* 起點座標 */
let lastX = 0;
let lastY = 0;
  1. 管理狀態:save(), restore()
  2. 變形:scale(), rotate(), translate(), transform(), setTransform()
  3. 畫面組成:globalAlpha, globalCompositionOperation
  4. 色彩與風格: strokeStyle,fillStyle,createLinearGradient(),createRadialGradient(), createPattern()
  5. 線條邊角及組合:lineWidth, lineCap, lineJoin, miterLimit
  6. 陰影:shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor
  7. 方形繪出:clearRect(), fillRect(), strokeRect()
  8. 路徑API:beginPath(), closePath(), moveTo(), lineTo(), quadraticCurveTo(), bezierCurveTo(), arcTo(), rect(), arc(), fill(), stroke(), clip(), isPointInPath()
  9. 焦點管理:drawFocusRing()
  10. 文字:font, textAlien, textBaseline, fillText(), strokeText(), measureText()
  11. 影像:drawImage(), createImageData(), getImageData(), putImageData()

繪圖函數與下筆(mousedown)監聽

重點:

  1. 監聽: 只有在 mousedown 時才會畫圖,mouseup & mouseout 不會。
  2. 要試訂下筆起始點,不然起始點的預設是左上角的(0,0),按照預設的話會從左上角連到下筆的位置。
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
canvas.addEventListener('mousedown', (e) => {
    isDrawing = true; 
    [lastX, lastY] = [e.offsetX, e.offsetY]; // 設定起始點
});

canvas.addEventListener('mousemove', draw); 

// 繪製函數;在 mousemove 的時候使用
function draw(e) {
    if(!isDrawing) return;  // 沒有允許繪製即退出

    /* 繪製路線 Setting */
    ctx.beginPath();  // 產生一個新路徑,產生後再使用繪圖指令來設定路徑。
    ctx.moveTo(lastX, lastY);  // 設定起點
    ctx.lineTo(e.offsetX, e.offsetY);  // 設定終點
    ctx.stroke();  // 依照設定開始繪製

    [lastX, lastY] = [e.offsetX, e.offsetY];  // 位置更新

    //當目前路徑為空(例如接著呼叫beginPath()完後)或是在一個新畫布上,不論為何,第一個路徑繪圖指令總是moveTo();因為每當重設路徑後,你幾乎都會需要設定繪圖起始點。

功能: 顏色

顏色使用 input type="color"
去監聽它的改變在動態寫入value

功能: 粗細

粗細的部分我已經寫好固定提供五個大小
五個圈圈搭被dataset,利用forEach 去監聽每個圈圈是否被點擊,點擊後動態寫入數值。


#canvas







Related Posts

Web開發學習筆記21 — RESTful Routes

Web開發學習筆記21 — RESTful Routes

該來理解 JavaScript 的原型鍊了

該來理解 JavaScript 的原型鍊了

The introduction and difference between class component and function component in React

The introduction and difference between class component and function component in React


Comments